from datetime import datetime
from sqlalchemy import desc, and_
import json
from flask import current_app

from backend.infrastructure.database import db
from backend.models.notification import Notification, NotificationSetting, WechatTemplate, NotificationLog
from backend.models.user import User
from backend.services.unified_log_service import UnifiedLogService

log_service = UnifiedLogService()


class NotificationService:
    """通知推送服务"""
    
    @staticmethod
    def create_notification(user_id, title, content, notification_type='system', 
                          priority='normal', related_type=None, related_id=None, 
                          template_id=None, send_wechat=True):
        """创建通知"""
        try:
            # 检查用户通知设置
            setting = NotificationSetting.query.filter(
                and_(NotificationSetting.user_id == user_id, 
                     NotificationSetting.notification_type == notification_type)
            ).first()
            
            # 如果用户禁用了该类型通知，则不创建
            if setting and not setting.enabled:
                return None
            
            # 创建通知记录
            notification = Notification(
                user_id=user_id,
                title=title,
                content=content,
                notification_type=notification_type,
                priority=priority,
                related_type=related_type,
                related_id=related_id,
                template_id=template_id
            )
            
            db.session.add(notification)
            db.session.commit()
            
            # 记录操作日志
            log_service.log_operation(
                user_id=user_id,
                action='CREATE',
                table_name='notifications',
                record_id=notification.id,
                details=f'创建通知: {title}'
            )
            
            # 发送微信消息
            if send_wechat and setting and setting.wechat_enabled:
                NotificationService.send_wechat_message(notification)
            
            return notification
            
        except Exception as e:
            db.session.rollback()
            current_app.logger.error(f'创建通知失败: {str(e)}')
            return None
    
    @staticmethod
    def get_user_notifications(user_id, page=1, per_page=20, status=None):
        """获取用户通知列表"""
        try:
            query = Notification.query.filter(Notification.user_id == user_id)
            
            if status:
                query = query.filter(Notification.status == status)
            
            pagination = query.order_by(desc(Notification.created_at)).paginate(
                page=page, per_page=per_page, error_out=False
            )
            
            return {
                'notifications': [notification.to_dict() for notification in pagination.items],
                'pagination': {
                    'page': page,
                    'per_page': per_page,
                    'total': pagination.total,
                    'pages': pagination.pages,
                    'has_next': pagination.has_next,
                    'has_prev': pagination.has_prev
                }
            }
            
        except Exception as e:
            current_app.logger.error(f'获取用户通知失败: {str(e)}')
            return {'notifications': [], 'pagination': {}}
    
    @staticmethod
    def mark_as_read(notification_id, user_id):
        """标记通知为已读"""
        try:
            notification = Notification.query.filter(
                and_(Notification.id == notification_id, Notification.user_id == user_id)
            ).first()
            
            if not notification:
                return False
            
            notification.status = 'read'
            notification.read_at = datetime.now()
            db.session.commit()
            
            return True
            
        except Exception as e:
            db.session.rollback()
            current_app.logger.error(f'标记通知已读失败: {str(e)}')
            return False
    
    @staticmethod
    def get_unread_count(user_id):
        """获取未读通知数量"""
        try:
            count = Notification.query.filter(
                and_(Notification.user_id == user_id, Notification.status == 'unread')
            ).count()
            return count
            
        except Exception as e:
            current_app.logger.error(f'获取未读通知数量失败: {str(e)}')
            return 0
    
    @staticmethod
    def send_wechat_message(notification):
        """发送微信模板消息（模拟实现）"""
        try:
            # 模拟发送成功
            notification.wechat_sent = True
            notification.wechat_sent_at = datetime.now()
            db.session.commit()
            return True
            
        except Exception as e:
            current_app.logger.error(f'发送微信消息失败: {str(e)}')
            return False 